package com.inspur.edp.formserver.vmmanager.service;

import com.google.common.util.concurrent.ServiceManager;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.util.MetadataUtil;
import com.inspur.edp.das.commonmodel.IElementCollection;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.formserver.viewmodel.action.MappedCdpAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelActionType;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.lcm.metadata.spi.IMetadataReferenceManager;
import com.inspur.edp.metadata.rtcustomization.api.CustomizationService;
import com.inspur.edp.metadata.rtcustomization.spi.IMetadataRtReferenceManager;
import io.iec.edp.caf.commons.exception.CAFRuntimeException;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MetadataRtReferenceService implements IMetadataRtReferenceManager {

  private HashMap<String, String> map = new HashMap<String, String>();
  private String errorCode = "MetadataReferenceService";
  //TODO 临时添加
  private String errorToken = "#GSPBefError# ";
  private void buildMetadataReference(GspMetadata metadata)
  {
    if (metadata.getRefs() == null)
    {
      metadata.setRefs(new ArrayList<MetadataReference>());
    }
    map.clear();

    CustomizationService service = SpringBeanUtils.getBean(CustomizationService.class);
    GspViewModel vm = (GspViewModel) metadata.getContent();
    // 虚拟vo无依赖
    if (vm.getIsVirtual())
    {
      return;
    }

    // ① vm.Mapping
    String beId = vm.getMapping().getTargetMetadataId();
    addMappingBeReference(vm,beId, metadata, service);

    // ② obj
    dealObjectReference(vm,vm.getMainObject(), metadata, service);

    // ③ vm.Actions
    if (vm.getActions() != null && vm.getActions().getCount() > 0)
    {
      for (ViewModelAction action : vm.getActions())
      {
        if (action.getType() == ViewModelActionType.VMAction)
        {
          if (action instanceof MappedCdpAction)
          {
            buildCompReference(vm,(MappedCdpAction) action, metadata, service);
          }
          else
          {
            throw new CAFRuntimeException("", errorCode,errorToken+action.getName()+"类型应为MappedCdpAction. "+errorToken , null, ExceptionLevel.Error,false);
          }
        }
      }
    }

    // ④ vm.DataExtendInfo
    //todo:
  }

  private void dealObjectReference(GspViewModel vm,GspViewObject obj, GspMetadata metadata, CustomizationService service)
  {
    if (obj.getIsVirtual())
    {
      return;
    }

    // ① mapping
    addMappingBeReference(vm,obj.getMapping().getTargetMetadataId(), metadata, service);

    // ① Elemnet
    if (obj.getContainElements() != null && obj.getContainElements().getCount() > 0)
    {
      for (IGspCommonField ele : obj.getContainElements())
      {
        dealElementReference( vm,(GspViewModelElement)ele, metadata, service);
      }
    }

    // ② Child
    if (obj.getContainChildObjects() != null && obj.getContainChildObjects().getCount() > 0)
    {
      for (IGspCommonObject childObj : obj.getContainChildObjects())
      {
        dealObjectReference(vm, (GspViewObject)childObj, metadata, service);
      }
    }
  }

  private void dealElementReference(GspViewModel vm,GspViewModelElement ele, GspMetadata metadata, CustomizationService service)
  {
    //① mapping
    if (!ele.getIsVirtualViewElement())
    {
      addMappingBeReference(vm,ele.getMapping().getTargetMetadataId(), metadata, service);
    }

    //② vmElement.Help
    //todo:
  }

  public void buildCompReference(GspViewModel vm,MappedCdpAction operation, GspMetadata metadata, CustomizationService service)
  {
    addMappingBeReference(vm,operation.getComponentEntityId(), metadata, service);
  }

  private void addMappingBeReference(GspViewModel vm,String refBeId, GspMetadata metadata, CustomizationService service)
  {
    if (refBeId==null ||"".equals(refBeId) || map.containsKey(refBeId))
    {
      return;
    }

    map.put(refBeId, refBeId);
    buildReference(vm,refBeId, metadata, service);
  }

  private void buildReference(GspViewModel vm,String refMetadataId, GspMetadata metadata, CustomizationService service)
  {
    if (refMetadataId==null || "".equals(refMetadataId))
    {
      return;
    }
    for (MetadataReference metadataReference : metadata.getRefs()) {
      if (refMetadataId.equals(metadataReference.getDependentMetadata().getId())) {
        return;
      }
    }
//    CustomizationService refService =SpringBeanUtils.getBean(CustomizationService.class);
    GspMetadata refMetaData= MetadataUtil.getCustomMetadata(refMetadataId);
    if(refMetaData==null){
      throw  new RuntimeException(String.format("编号为：%1$s，名称为：%2$s，ID为：%3$s的VO元数据在构造依赖的元数据关系时，未找到ID值为：%4$s的元数据,请确认依赖的元数据是否部署到环境中!",
          vm.getCode(),vm.getName(),vm.getID(),refMetadataId));
    }
    MetadataReference metadataReference = new MetadataReference();
    metadataReference.setMetadata(metadata.getHeader());
    metadataReference.setDependentMetadata(refMetaData.getHeader());
    metadata.getRefs().add(metadataReference);
  }

  public List<MetadataReference> getConstraint(GspMetadata metadata)
  {
    if(metadata.getRefs()!=null){
      metadata.getRefs().clear();
    }
    buildMetadataReference(metadata);
    List<MetadataReference> list = new ArrayList<>();
    if (metadata.getRefs() != null && metadata.getRefs().size() > 0)
    {
      for (MetadataReference item : metadata.getRefs())
      {
        list.add(item);
      }
    }
    return list;
  }
}
